package xyz.hlh.filter;

import cn.hutool.json.JSONUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import xyz.hlh.common.Constant;
import xyz.hlh.common.Result;
import xyz.hlh.config.LoginProperties;
import xyz.hlh.entity.User;

import javax.annotation.Resource;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.TimeUnit;

/**
 * @author HLH
 * @email 17703595860@163.com
 * @date : Created in  2021/8/1 下午8:13
 */
public class LoginFilter implements Filter {

    private final RedisTemplate<String, Object> redisTemplate;
    private final LoginProperties loginProperties;

    public LoginFilter(RedisTemplate<String, Object> redisTemplate, LoginProperties loginProperties) {
        this.redisTemplate = redisTemplate;
        this.loginProperties = loginProperties;
    }

    @Override
    public void init(FilterConfig filterConfig) {
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest httpServletRequest = (HttpServletRequest) request;
        // 过滤路径
        String requestURI = httpServletRequest.getRequestURI();
        if (!loginProperties.getFilterExcludeUrl().contains(requestURI)) {
            // 获取token
            String token = httpServletRequest.getHeader(Constant.TOKEN_HEADER_NAME);
            if (StringUtils.isBlank(token)) {
                returnNoLogin(response);
                return;
            }
            // 从redis中拿token对应user
            User user = (User) redisTemplate.opsForValue().get(Constant.REDIS_USER_PREFIX + token);
            if (user == null) {
                returnNoLogin(response);
                return;
            }
            // token续期
            redisTemplate.expire(Constant.REDIS_USER_PREFIX + token, 30, TimeUnit.MINUTES);
        }
        chain.doFilter(request, response);
    }

    /**
     * 返回未登录的错误信息
     * @param response ServletResponse
     */
    private void returnNoLogin(ServletResponse response) throws IOException {
        HttpServletResponse httpServletResponse = (HttpServletResponse) response;
        ServletOutputStream outputStream = httpServletResponse.getOutputStream();
        // 设置返回401 和响应编码
        httpServletResponse.setStatus(401);
        httpServletResponse.setContentType("Application/json;charset=utf-8");
        // 构造返回响应体
        Result<String> result = Result.<String>builder()
                .code(HttpStatus.UNAUTHORIZED.value())
                .errorMsg("未登陆，请先登陆")
                .build();
        String resultString = JSONUtil.toJsonStr(result);
        outputStream.write(resultString.getBytes(StandardCharsets.UTF_8));
    }

    @Override
    public void destroy() {
    }

}
